package com.demo.config;

import org.aopalliance.aop.Advice;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.aspectj.AspectJPointcutAdvisor;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
import org.springframework.transaction.interceptor.TransactionAttribute;
import org.springframework.transaction.interceptor.TransactionInterceptor;

@Aspect
@Configuration
public class TransactionConfig {

	@Autowired
	PlatformTransactionManager ptm;
	
	/**
	 * 配置事务拦截器(给哪些方法配置什么事务属性)
	 * @return
	 */
	@Bean
	public TransactionInterceptor m1() {
		DefaultTransactionAttribute attr1 = new DefaultTransactionAttribute();//定义required事务属性,给增删改
		attr1.setPropagationBehavior(DefaultTransactionAttribute.PROPAGATION_REQUIRED);
		
		DefaultTransactionAttribute attr2 = new DefaultTransactionAttribute();//定义required事务属性,给查询类的方法
		attr2.setPropagationBehavior(DefaultTransactionAttribute.PROPAGATION_REQUIRED);
		attr2.setReadOnly(true);
		
		NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
		source.addTransactionalMethod("save*", attr1);
		source.addTransactionalMethod("delete*", attr1);
		source.addTransactionalMethod("update*", attr1);
		
		source.addTransactionalMethod("get*", attr2);
		source.addTransactionalMethod("list*", attr2);
		source.addTransactionalMethod("search*", attr2);
		source.addTransactionalMethod("count*", attr2);
		source.addTransactionalMethod("is*", attr2);
		
		return new TransactionInterceptor(ptm, source);
	}
	
	/**
	 * 配置切入点,绑定事务拦截器配置
	 * @return
	 */
	@Bean
	public Advisor m2() {
		AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
		pointcut.setExpression("execution(* com.demo.service.*.*(..))");
		return new DefaultPointcutAdvisor(pointcut, m1());
	}
	
	
}
